﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TCOE.ToolKits.Geolocation;
using System.IO;

namespace GisGen
{
    public partial class frmCaptionGenerate : Form
    {
        public frmCaptionGenerate()
        {
            InitializeComponent();
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            decimal hour = nudHour.Value;
            decimal minute = nudMinute.Value;
            decimal second = nudSecond.Value;
            double min = (double)nudMin.Value;
            double max = (double)nudMax.Value;

            decimal totalSecond = hour * 3600 + minute * 60 + second;

            // 计算显示距离、速度
            IList<GpsPoint> lstGpsPoint = ConvertToGpsPoint(txtSource.Text.Trim(), true);
            if (lstGpsPoint.Count < 2)
            {
                MessageBox.Show("请输入两个以上坐标点");
            }

            //计算总距离、速度
            double distance = 0.00;
            for (int i = 0; i < lstGpsPoint.Count; i++)
            {
                if (i > 0)
                {
                    distance += CoordCompute.GetDistance(lstGpsPoint[i].Longitude, lstGpsPoint[i].Latitude, lstGpsPoint[i - 1].Longitude, lstGpsPoint[i - 1].Latitude);
                }
            }

            double speed = distance / (double)totalSecond;
            double knSpeed = (distance / (double)totalSecond) * ((double)3600 / (double)1852);
            lblDistance.Text = distance.ToString("F4") + "m";
            lblSpeed.Text = speed.ToString("F4") + "m/s (" + knSpeed.ToString("F4") + "Kn)";

            // 每秒生成一个坐标点
            IList<GpsPoint> list = new List<GpsPoint>();
            string strGpsPoints = "";
            Random rd = new Random();
            for (int j = 1; j < lstGpsPoint.Count; j++)
            {
                IList<GpsPoint> lstGenPoint = GeneratePoint(lstGpsPoint[j - 1], lstGpsPoint[j], distance / (double)totalSecond, min, max);
                if (j != 1)
                {
                    lstGenPoint.RemoveAt(0);
                }
                foreach (GpsPoint p in lstGenPoint)
                {
                    // 对坐标进行偏移
                    if (min != 0 || max != 0)
                    {
                        double offset = (rd.Next((int)min, (int)max) + rd.NextDouble()) / (double)100 / (double)100000;
                        p.Longitude = p.Longitude + offset;
                    }

                    list.Add(p);
                    strGpsPoints += p.Latitude.ToString("F6") + "," + p.Longitude.ToString("F6") + ";\r\n";
                }
            }
            txtGenerate.Text = strGpsPoints;

            string strCaption = "";
            for (int i = 0; i < totalSecond; i++)
            {
                if (i < list.Count)
                {
                    strCaption += (i + 1) + "\r\n";
                    strCaption += SecondToTime(i) + ",000 --> " + SecondToTime(i + 1) + ",000\r\n";
                    strCaption += list[i].Latitude.ToString("F6") + "," + list[i].Longitude.ToString("F6") + "\r\n\r\n";
                }
                else
                {
                    strCaption += (i + 1) + "\r\n";
                    strCaption += SecondToTime(i) + ",000 --> " + SecondToTime(i + 1) + ",000\r\n";
                    strCaption += list[list.Count - 1].Latitude.ToString("F6") + "," + list[list.Count - 1].Longitude.ToString("F6") + "\r\n\r\n";
                }
            }
            txtCaption.Text = strCaption;
        }

        /// <summary>
        /// 坐标字符串转换为坐标列表
        /// </summary>
        /// <param name="strPoints">坐标字符串</param>
        /// <param name="isLatLng">坐标是（纬度，经度）格式（true:纬度，经度，false:经度，纬度）</param>
        /// <returns></returns>
        private IList<GpsPoint> ConvertToGpsPoint(string strPoints, bool isLatLng)
        {
            strPoints = strPoints.Replace("\r\n", "");
            string[] points = strPoints.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);

            IList<GpsPoint> lstPoint = new List<GpsPoint>();
            foreach (string strPoint in points)
            {
                string[] latLng = strPoint.Split(',');
                GpsPoint point = new GpsPoint();
                if (isLatLng)
                {
                    //纬度，经度
                    point.LatitudeText = latLng[0];
                    point.LongitudeText = latLng[1];
                }
                else
                {
                    //经度，纬度
                    point.LatitudeText = latLng[1];
                    point.LongitudeText = latLng[0];
                }

                lstPoint.Add(point);
            }
            return lstPoint;
        }

        /// <summary>
        /// 生成坐标列表
        /// </summary>
        /// <param name="start">起始坐标</param>
        /// <param name="end">结束坐标</param>
        /// <param name="min">最小点距</param>
        /// <param name="max">最大点距</param>
        /// <returns>生成后坐标列表</returns>
        private IList<GpsPoint> GeneratePoint(GpsPoint start, GpsPoint end, double interval, double min, double max)
        {
            IList<GpsPoint> lstPoint = new List<GpsPoint>();
            lstPoint.Add(start);

            double distance = CoordCompute.GetDistance(start.Longitude, start.Latitude, end.Longitude, end.Latitude);
            double k_x = (end.Longitude - start.Longitude) / distance;  //x比斜边
            double k_y = (end.Latitude - start.Latitude) / distance;    //y比斜边


            Random ran = new Random();

            int i = 0; //计数器
            double d = interval;
            while (d < distance)
            {
                i++;
                double x = d * k_x + start.Longitude;
                double y = d * k_y + start.Latitude;

                GpsPoint point = new GpsPoint();
                point.Longitude = x;
                point.Latitude = y;
                lstPoint.Add(point);

                d += interval;
            }

            lstPoint.Add(end);

            return lstPoint;
        }

        /// <summary>
        /// 秒转换为时分秒字符串
        /// </summary>
        /// <param name="seconds">秒数</param>
        /// <returns>时：分：秒字符串，例：02:04:02</returns>
        private String SecondToTime(int seconds)
        {
            String strTime = "";
            if (seconds <= 0)
            {
                return "00:00:00";
            }

            int hour = 0;
            int minute = 0;
            int second = 0;
            minute = seconds / 60;
            if (minute < 60)
            {
                second = seconds % 60;
                strTime = "00:" + unitFormat(minute) + ":" + unitFormat(second);
            }
            else
            {
                hour = minute / 60;
                if (hour > 99)
                    return "99:59:59";
                minute = minute % 60;
                second = seconds - hour * 3600 - minute * 60;
                strTime = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
            }

            return strTime;
        }

        /// <summary>
        /// 个位数字格式化两位显示
        /// </summary>
        /// <param name="i">数字</param>
        /// <returns></returns>
        public static String unitFormat(int i)
        {
            String retStr = null;
            if (i >= 0 && i < 10)
                retStr = "0" + i;
            else
                retStr = "" + i;
            return retStr;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            sfdSaveFile.FileName = "字幕.srt";
            if(sfdSaveFile.ShowDialog() != DialogResult.OK){
                return;
            }

            string fileName = sfdSaveFile.FileName;
            WriteFileText(fileName,txtCaption.Text);
        }

        // 写文件
        public bool WriteFileText(string fileName, string strText)
        {
            try
            {
                byte[] bytes = System.Text.Encoding.Default.GetBytes(strText);
                File.WriteAllBytes(fileName, bytes);
                return true;
            }
            catch (Exception err)
            {
                throw err;
            }

        }
    }
}
